package com.gxa.community.admin.service.system.impl;

import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gxa.community.admin.mapper.system.RoleMapper;
import com.gxa.community.admin.service.system.RoleService;
import com.gxa.community.core.pojo.domain.AdminRole;
import com.gxa.community.core.pojo.domain.Menu;
import com.gxa.community.core.pojo.dto.system.RoleMenuDTO;
import com.gxa.community.core.pojo.dto.system.RoleNameDTO;
import com.gxa.community.core.pojo.vo.system.MenuVo;
import com.gxa.community.core.utils.R;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Slf4j
@Service
public class RoleServiceImpl extends ServiceImpl<RoleMapper, AdminRole> implements RoleService {

    @Autowired
    private RoleMapper roleMapper;

    @Override
    public List<RoleNameDTO> getAllRoleNames() {
        List<RoleNameDTO> roleNameDTOS = roleMapper.selectAllRoleName();
        return roleNameDTOS;
    }
    //删除角色时，删除角色菜单中间表相关信息
    @Override
    public Boolean delRoleMenuRelativeByRoleId(Integer id) {
        Integer result = roleMapper.deleteRoleMenuRelativeByRoleId(id);
        return result > 0?true:false;
    }

    //树形组件数据返回
    //根据角色id查询单个角色信息，查询当前登录用户的所有权限列表
    @Override
    public R getSingleRoleInfo(Integer id) {
        RoleMenuDTO roleMenuDTO = new RoleMenuDTO();
        //先查询当前角色id信息
        AdminRole adminRole = roleMapper.selectById(id);
        //获取当前角色id的所有菜单
        List<Menu> menus = roleMapper.selectMenusByRoleId(id);
        //对该角色id的菜单进行视图数据封装
        List<MenuVo> menuVos = transferMenuVo(menus, 0);
        //最后对DTO对象进行封装
        roleMenuDTO.setId(adminRole.getId());
        roleMenuDTO.setName(adminRole.getName());
        roleMenuDTO.setRemark(adminRole.getRemark());
        roleMenuDTO.setCreateTime(adminRole.getCreateTime());
        roleMenuDTO.setMenu(menuVos);
        return R.ok("查询成功！").put("data",roleMenuDTO);
    }
    //当前登录用户菜单数据封装
    private List<MenuVo> transferMenuVo(List<Menu> menus, Integer parentId) {
        List<MenuVo> resultList = new ArrayList<>();
        if (!CollectionUtils.isEmpty(menus)){
            for (Menu menu : menus) {
                if (parentId.intValue() == menu.getParentId().intValue()){
                    MenuVo menuVo = new MenuVo();
                    //浅拷贝
                    BeanUtils.copyProperties(menu,menuVo);
                    //递归查询子菜单，并封装信息
                    List<MenuVo> childList = transferMenuVo(menus,menu.getId());
                    if (!CollectionUtils.isEmpty(childList)){
                        menuVo.setChild(childList);
                    }
                    resultList.add(menuVo);
                }
            }
        }
        return resultList;
    }

    //查询所有权限
    @Override
    public R getAllMenu() {
        List<Menu> menus = roleMapper.selectAllMenu();
        if (CollectionUtils.isEmpty(menus)){
            return R.error(600,"查询失败！");
        }
        //对菜单进行视图数据封装
        List<MenuVo> menuVos = transferMenuVo(menus, 0);
        return R.ok("查询成功！").put("data",menuVos);
    }

    //新增角色
    @Override
    public R addRole(RoleMenuDTO roleMenuDTO) {
        //先增加角色，向角色表塞数据
        roleMenuDTO.setCreateTime(new Date().getTime());
        AdminRole adminRole = new AdminRole(null,roleMenuDTO.getName(),roleMenuDTO.getRemark(),new Date().getTime());
        int result1 = roleMapper.insert(adminRole);
        //再向角色与菜单中间表塞数据
        List<MenuVo> menus = roleMenuDTO.getMenu();
        Integer result2 = insertDataIntoRoleMenuRelative(menus, adminRole.getId());
        log.info("中间表塞了{}条数据",result2);
        return result1 > 0?R.ok("添加成功！"):R.error(600,"添加失败,请联系管理员！");
    }
    public Integer insertDataIntoRoleMenuRelative(List<MenuVo> menuVos,Integer roleId){
        Integer count = 0;
        for (MenuVo menuVo : menuVos) {
            Integer menuId = menuVo.getId();
            roleMapper.insertIntoRoleMenu(roleId,menuId);
            count++;
            //如果child不为空，继续将child中的数据插入中间表
            if (!CollectionUtils.isEmpty(menuVo.getChild())){
                insertDataIntoRoleMenuRelative(menuVo.getChild(),roleId);
            }
        }
        return count;
    }

    //修改角色信息
    @Override
    public R updataSingleRole(RoleMenuDTO roleMenuDTO) {
        //先修改角色表
        AdminRole adminRole = new AdminRole(roleMenuDTO.getId(),roleMenuDTO.getName(),roleMenuDTO.getRemark(),roleMenuDTO.getCreateTime());
        boolean result1 = this.saveOrUpdate(adminRole);
        //再删除角色菜单中间表信息
        Integer roleId = roleMenuDTO.getId();
        roleMapper.deleteRoleMenuRelativeByRoleId(roleId);
        //最后向角色菜单中间表塞入权限信息
        List<MenuVo> menus = roleMenuDTO.getMenu();
        Integer result2 = insertDataIntoRoleMenuRelative(menus, adminRole.getId());
        log.info("中间表塞了{}条数据",result2);
        return result1?R.ok("修改成功！"):R.error(600,"修改失败,请联系管理员！");
    }
}
